<?php

namespace adapterPattern;

/**
 * 适配器模式主要角色和职责
 * 1. 目标接口(Target)：客户端希望使用的接口
 * 2. 适配器类(Adapter)：实现了目标接口，并通过委托的方式将请求转化为适配的接口
 * 3. 适配者类(Adaptee)：已有的、需要适配的类
 * 4. 客户端调用(Client)
 */

/**
 * 这里我举个生活中的常见例子：手机的电源适配器
 * 1. 一般的手机通过数据线进行充电，在这里认为数据线的接口是USB的
 * 2. 但是我们的插座一般是没有提供USB接口的，一般都是双孔和三孔
 * 3. 这时候就需要电源适配器，将双口转化为USB接口以用于充电
 * 这里的 数据线的USB口==目标接口， 电源适配器==适配器类， 双控插座==适配者类
 */

// 以多格式的影音播放器为例，我们用适配器模式实现一个简单的播放器系统。

// 1. 目标接口
interface AudioPlayer
{
    public function play(string $audioType, string $fileName): void;
}

// 2. 定义高级媒体接口，表示系统目前不支持、但是要适配的新格式。
interface AdvancedMediaPlayer
{
    public function playVlc(string $fileName): void;
    public function playMp4(string $fileName): void;
}

// 3. 实现高级媒体接口
class VlcPlayer implements AdvancedMediaPlayer
{
    public function playMp4(string $fileName): void
    {
        // 什么都不做
    }

    public function playVlc(string $fileName): void
    {
        echo "播放VLC格式的文件：{$fileName}";
    }
}
class Mp4Player implements AdvancedMediaPlayer
{
    public function playMp4(string $fileName): void
    {
        echo "播放Mp4格式的文件：{$fileName}";
    }

    public function playVlc(string $fileName): void
    {
        // 什么都不做
    }
}

// 4. 定义适配器类：桥接高级播放器和目标接口
// 这一步是适配器的核心，通过 MediaAdapter 将外部的高级播放器"包一层”，让它看起来像是 AudioPlayer 的实现，这样旧系统就可以无感接入新格式。
class MediaAdapter implements AudioPlayer
{
    public function play(string $audioType, string $fileName): void
    {
        switch ($audioType) {
            case 'vlc':
                (new VlcPlayer())->playVlc($fileName);
                break;
            case 'mp4':
                (new Mp4Player())->playMp4($fileName);
                break;
            default:
                echo "不支持此格式：{$audioType}";
                break;
        }
    }
}

// 5. 定义默认类，默认使用mp3格式
class DefaultPlayer implements AudioPlayer
{
    public function play(string $audioType, string $fileName): void
    {
        // 默认使用mp3
        if ($audioType == 'mp3') {
            echo "播放mp3格式的文件：{$fileName}";
        } else {
            (new MediaAdapter())->play($audioType, $fileName);
        }
    }
}

// 测试
$player = new DefaultPlayer();
$player->play('mp3', 'test.mp3');
echo "\n";
$player->play('vlc', 'test.vlc');
echo "\n";
$player->play('mp4', 'test.mp4');
echo "\n";
$player->play('avi', 'test.avi');